Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for making the already existing FormExtender feature work #115

Merged
merged 2 commits into from
Jun 27, 2018

Conversation

sunew
Copy link
Contributor

@sunew sunew commented Jun 20, 2018

Portlet add and edit forms already extend AutoExtensibleForm from plone.autoform. (Added in 2014 in fc15814).

That means it is (before this PR) possible to extend portlet forms with a FormExtender.

But some portlet AddForms fail when creating the Assignment, if there is a FormExtender for the form, and the addform uses Assignment(**data) for creation instead of explicit parameters.
This PR fixes this by filtering away data values that does not come from the 'core' schema.

How to extend the schema of all/one portlet(s)

First define a schema and a formextender:

class IPortletCssClass(Interface):
    """ Schema for portlet css class  """

    # in real life this would be a Choice field with a vocabulary, editable in a controlpanel:
    css_class = schema.TextLine(
        title=u'Portlet appearance',
        required=False
    )

class PortletCssClassFormExtender(FormExtender):

    def update(self):
        self.add(IPortletCssClass, prefix="portletcssclass")

register it for add and edit forms - in this case for all portlets, but you can be selective on an individual portlet add or edit form interface:


  <adapter
      for="zope.interface.Interface
           zope.publisher.interfaces.browser.IDefaultBrowserLayer
           plone.app.portlets.browser.interfaces.IPortletAddForm"
      factory=".formextender.PortletCssClassFormExtender"
      provides="plone.z3cform.fieldsets.interfaces.IFormExtender"
      name="portletcssclass.extender" />
  <adapter
      for="zope.interface.Interface
           zope.publisher.interfaces.browser.IDefaultBrowserLayer
           plone.app.portlets.browser.interfaces.IPortletEditForm"
      factory=".formextender.PortletCssClassFormExtender"
      provides="plone.z3cform.fieldsets.interfaces.IFormExtender"
      name="portletcssclass.extender" />

then define an storage adapter for the extended fields. Here I choose to store the data in as PortletAssignmentSettings:

class PortletCssClassAdapter(object):
    adapts(IPortletAssignment)
    implements(IPortletCssClass)

    def __init__(self, context):
        # avoid recursion
        self.__dict__['context'] = context

    def __setattr__(self, attr, value):
        settings = IPortletAssignmentSettings(self.context)
        settings[attr] = value

    def __getattr__(self, attr):
        settings = IPortletAssignmentSettings(self.context)
        return settings.get(attr, None)

register the storage adapter:

<adapter factory=".storage.PortletCssClassAdapter"/>

@sunew sunew force-pushed the fix-formextender branch from d7510b4 to 889257b Compare June 20, 2018 23:22
@sunew sunew changed the title WIP: Fix for making the already existing FormExtender feature work Fix for making the already existing FormExtender feature work Jun 20, 2018
Copy link
Member

@jensens jensens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall great you made it work! Just some minor style issues.

# -*- coding: utf-8 -*-

from plone.app.portlets.browser.interfaces import (IPortletAddForm,
IPortletEditForm)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks:) yep, my isort was missing the recommended plone config (i suggest we add this to the setup.cfg ? )


class PortletCssClassAdapter(object):
adapts(IPortletAssignment)
implements(IPortletCssClass)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use the class decorators @adapter and @Implementer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jensens done

sunew added 2 commits June 27, 2018 01:51
…rms fail on creating the Assignment, if there is a FormExtender for the form,

and the addform uses "Assignment(**data)" for creation and not "Assignment(key=data.get(key, None))".
Fix this by filtering away data values that does not come from the 'core' schema.
@sunew sunew force-pushed the fix-formextender branch from 889257b to a7d16da Compare June 26, 2018 23:52
@sunew sunew merged commit 943d2c6 into master Jun 27, 2018
@sunew sunew deleted the fix-formextender branch June 27, 2018 09:42
jensens added a commit that referenced this pull request Aug 10, 2018
backport "Fix for making the already existing FormExtender feature work #115" to 4.3.x branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants